package com.douqu.game.core.factory;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.douqu.game.core.config.*;
import com.douqu.game.core.config.activity.CampRobotConfig;
import com.douqu.game.core.config.card.CardConfig;
import com.douqu.game.core.config.card.LegionChainConfig;
import com.douqu.game.core.config.challenge.ExpeditionConfig;
import com.douqu.game.core.config.common.CommonData;
import com.douqu.game.core.config.common.GoodsData;
import com.douqu.game.core.config.goods.PropConfig;
import com.douqu.game.core.config.map.CityConfig;
import com.douqu.game.core.config.map.WorldMapTaskBoxConfig;
import com.douqu.game.core.config.store.GoblinStoreConfig;
import com.douqu.game.core.config.talent.TalentRefineConfig;
import com.douqu.game.core.config.talent.TalentUpConfig;
import com.douqu.game.core.e.E_LegionChinaType;
import com.douqu.game.core.e.E_StableDataType;
import com.douqu.game.core.entity.GameObject;
import com.douqu.game.core.i.ICalculateRandomField;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.util.StringUtils;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Author : Bean
 * 2017-07-06 16:13
 */
public class DataFactory implements Serializable
{
    private static final long serialVersionUID = 1L;

    private static DataFactory instance = null;

    private static DataFactory testInstance = null;

    /**
     * 当前时间(毫秒)
     */
    public static long currentTime = System.currentTimeMillis();


    private DataFactory(){}

    /**
     * 只有在加载时调用的方法才需要传tetLoad这个参数,游戏运行中不传
     * @param testLoad
     * @return
     */
    public static DataFactory getInstance(boolean... testLoad)
    {
        if(testLoad.length > 0 && testLoad[0])
        {
            if (testInstance == null) {
                testInstance = new DataFactory();
            }
            return testInstance;
        }
        else
        {
            if (instance == null) {
                instance = new DataFactory();
            }
            return instance;
        }
    }

    /**
     * 分支服务器的时候需要用
     * @param dataFactory
     */
    public void set(DataFactory dataFactory)
    {
        instance = dataFactory;

        List<AttributeConfig> list = instance.getDataList(DataFactory.ATTRIBUTE_KEY);
        for(AttributeConfig attributeConfig : list)
        {
            attributeConfig.check();
        }
    }


    /**
     * 初始化数据
     */
    //private InitDataConfig initDataConfig;

//    public void setInitDataConfig(InitDataConfig initDataConfig){
//        this.initDataConfig = initDataConfig;
//    }
//
//    public InitDataConfig getInitDataConfig(){
//        return this.initDataConfig;
//    }

    /**
     * 最高玩家等级
     */
    public int MAX_PLAYER_LV;


    /** 兵种配置 */
    public final static int SOLDIER_KEY = 1;
    /** 怪物主将属性配置 */
    public final static int MASTER_PARAM_KEY = 2;
    /** 等级经验配置 */
    public final static int PLAYER_LV_KEY = 3;
    /** 资源 */
    public final static int ASSET_KEY = 4;
    /** 卡牌配置 */
    public final static int CARD_KEY = 5;
    /** 卡牌升级配置 */
    public final static int CARD_LV_KEY = 6;
    /** 关卡配置 */
    public final static int LEVEL_KEY = 7;
    /** 副本配置 */
    public final static int INSTANCE_KEY = 8;
    /** 道具配置 */
    public final static int PROP_KEY = 9;
    /** 怪物配置 */
    public final static int MONSTER_KEY = 10;
    /** 段位配置 */
    public final static int GRADE_KEY = 11;
    /** 掉落配置 */
    public final static int DROP_GROUP_KEY = 12;
    /** 技能配置 */
    public final static int SKILL_KEY = 13;
    /** 属性配置 */
    public final static int ATTRIBUTE_KEY = 14;
    /** 职业配置 */
    public final static int PROFESSION_KEY = 15;
    /** 十连抽配置 */
    public final static int LOTTERY_KEY = 16;
    /** 评星配置 */
    public final static int STAR_CHECK_KEY = 17;
    /** 竞技场每日奖励配置 */
    public final static int ARENA_DAILY_REWARD_KEY = 18;
    /** 兑换奖励配置 */
    public final static int REWARD_KEY = 19;
    /** BUFF配置 */
    public final static int BUFF_KEY = 20;
    /** 主将配置 */
    public final static int MASTER_KEY = 21;
    /** 祭坛配置*/
    public final static int ALTAR_KEY = 22;
    /** 官阶战配置*/
    public final static int OFFICIAL_RANK_KEY = 23;
    /** 官阶战积分兑换奖励配置*/
    public final static int OFFICIAL_INTEGRAL_REWARD_KEY = 24;
    /** 任务配置*/
    public final static int TASK_KEY = 25;
    /** 活跃宝箱配置*/
    public final static int ACTIVE_BOX_KEY = 26;
    /** 成长宝箱配置*/
    public final static int GROW_UP_BOX_KEY = 27;
    /** 随机名字库*/
    public final static int PLAYER_NAME_KEY = 28;
    /** 哥布林商店配置*/
    public final static int GOBLIN_STORE_KEY = 29;
    /** 饰品强化配置*/
    public final static int ACCESSORY_INTENSIFY_KEY = 30;
    /** 装备配置*/
    public final static int EQUIP_KEY = 31;
    /** 装备强化配置*/
    public final static int EQUIP_INTENSIFY_KEY = 32;
    /**饰品进阶*/
    public final static int ACCESSORY_UP_KEY = 33;
    /**卡片升星*/
    public final static int CARD_STAR_KEY = 34;
    /**卡片宿命*/
    public final static int CARD_FATE_KEY = 35;
    /**饰品表*/
    public final static int ACCESSORY_KEY = 36;
    /** 固定的配置数据 */
    public final static int STABLE_DATA_KEY = 37;
    /** 分解的配置数据 */
    public final static int RESOLVE_DATA_KEY = 38;
    /** 大地图的路线 */
    public final static int ROUTE_KEY = 39;
    /** 远征军 */
    public final static int CITY_EXPEDITION_KEY = 40;
    /** 英雄圣殿 */
    public final static int HERO_TEMPLE_KEY = 41;
    /** 解锁配置 */
    public final static int FUNCTION_KEY = 42;
    /**VIP配置**/
    public final static int VIP_KEY = 43;
    /**充值配置**/
    public final static int RECHARGE_KEY = 44;
    /**购买次数对应价格配置**/
    public final static int PURCHASE_KEY = 45;
    /**每日签到配置**/
    public final static int DAILY_SIGN_KEY = 46;
    /**地图**/
    public final static int MAP_KEY = 47;
    /**基金返回**/
    public final static int FUND_REWARD_KEY = 48;
    /**累计登陆奖励**/
    public final static int LOGIN_TIMES_REWARD_KEY = 49;
    /** 星级增加属性配置 */
    public final static int CARD_STAR_ATTRIBUTE_KEY = 50;
    /**官方邮件模板**/
    public final static int MAIL_MODEL_KEY = 51;
    /**远征**/
    public final static int EXPEDITION_KEY = 52;
    /**军团连锁**/
    public final static int LEGION_CHAIN_KEY = 53;
    /**主将培养**/
    public final static int MASTER_TRAIN_KEY = 54;
    /** 阵营活动机器人配置 */
    public final static int CAMP_ROBOT_KEY = 55;
    /** 专业技能配置 */
    public final static int MAJOR_KEY = 56;
    /** 专业合成配置 */
    public final static int MAJOR_MERGE_KEY = 57;
	/** 世界BOSS战 */
    public final static int WORLD_BOSS_KEY = 58;
    /** 世界BOSS等级参数 */
    public final static int WORLD_BOSS_PARAM_KEY = 59;
	/** 竞技场机器人 */
    public final static int ARENA_ROBOT_KEY = 60;
	/** 拍卖行配置 */
    public final static int WORLD_AUCTION_KEY = 61;
    /** mall 商店 */
    public final static int MALL_STORE_KEY = 62;
    /** 广告 */
    public final static int AD_KEY = 63;
    /** AI */
    public final static int AI_KEY = 64;
    /** 城 */
    public final static int CITY_KEY = 65;
    /** 军队 */
    public final static int CITY_ARMY_KEY = 66;
    /** 军队属性组 */
    public final static int CITY_ARMY_GROUP_KEY = 67;
    /** 卡组战斗参数 */
    public final static int CARD_PARAM_KEY = 68;
    /** 充值攻略对应项目 */
    public final static int RECHARGE_GUIDE_ITEM_KEY = 69;
    /** 充值攻略 */
    public final static int RECHARGE_GUIDE_KEY = 70;
    /** 限时活动 */
    public final static int TIME_LIMIT_ACTIVITY_KEY = 71;

    /** 战场争锋任务列表 */
    public final static int WORLD_MAP_TASK = 72;
    /** 战场争锋等级对应军功 */
    public final static int WORLD_MAP_TASK_GROUP = 73;
    /** 战场争锋宝箱 */
    public final static int WORLD_MAP_TASK_BOX = 74;

    /** 限时促销 */
    public final static int FLASH_SALE_KEY = 75;

    /** 分享 */
    public final static int SHARE_KEY = 76;
    /** 排行榜奖励表 */
    public final static int RANK_REWARD_KEY = 77;

    /** 初始化表 */
    public final static int INIT_DATA = 78;

    /** 连杀表 */
    public final static int HEGEMONY_SKILL_COUNT = 79;

    /** 等级差表 */
    public final static int HEGEMONY_LV_DIF = 80;

    /** 争霸赛排行奖励组 */
    public final static int HEGEMONY_RANK_REWARD_GROUP = 81;

    /** 争霸赛排行奖励 */
    public final static int HEGEMONY_RANK_REWARD = 82;

    /** 大地图城市掉落组 */
    public final static int CITY_DROP_GROUP = 83;

    /** 大地图城市掉落 */
    public final static int CITY_DROP       = 84;

    /** 在线奖励 */
    public final static int ONLINE_REWARD = 85;
    /** 活动大厅 */
    public final static int ACTIVITY_HALL = 86;
    /** 开服7天活动 */
    public final static int SEVEN_DAY_REWARD = 87;
    /** 开服活动积分礼包 */
    public final static int SEVEN_ACTIVITIES_REWARD = 88;
    /** 开服7天活动类型 */
    public final static int SEVEN_TAB = 89;
    /** 检测引导类型 */
    public final static int GUIDE_TYPE = 90;
    /** 天赋类型 */
    public final static int TALENT_BEAN = 91;
    /** 天赋升级 */
    public final static int TALENT_REFINE = 92;
    /** 天赋升级 */
    public final static int TALENT_UP = 93;
    /** 天赋升级经验类型 */
    public final static int TALENT_LEVEL = 94;

    private Map<Integer,List> dataList = new ConcurrentHashMap<>();

    private Map<Integer,Map> dataMap = new ConcurrentHashMap<>();

    /**
     * 有错误的配置文件
     */
    private List<String> errorList = new CopyOnWriteArrayList<>();

    public synchronized void clearData()
    {
        dataList.clear();
        dataMap.clear();
        errorList.clear();
        expeditionWeightMap.clear();
    }

    public void init()
    {
        checkConfig();

        initCardFate();
        initExpedition();
        initMasterTrain();
        initCampActivityRobot();

        initTalent();
    }

    public void addError(String errorFileName, String key, String value, int id)
    {
        if("check".equals(key))
            errorList.add(errorFileName + " Check Error -> id: " + id + ", value:" + value);
        else if("word".equals(key))
            errorList.add(errorFileName + " Word Error -> " + value);
        else
            errorList.add(errorFileName + " Field Error -> {id=" + id + ",key=" + key + ",value=" + value + "}");
    }


    public <T> void addData(int key, List<T> list, Map<Integer,T> map)
    {
        dataList.put(key, list);
        dataMap.put(key, map);
    }

    public <T> List<T> getDataList(int key)
    {
        return dataList.get(key);
    }

    public <T> Map<Integer, T> getDataMap(int key)
    {
        return dataMap.get(key);
    }

    public List<String> getErrorList()
    {
        return errorList;
    }

    public <T> T getGameObject(int key, int id)
    {
        Map map = getDataMap(key);
        if(map != null)
            return (T) map.get(id);

        return null;
    }

    public int getDataSize(int key) {
    	return getDataList(key).size();
    }

//    /**
//     * 验证 商店配置表
//     * @return
//     */
//    public boolean checkGoblinStoreConfig(){
//        List<GoblinStoreConfig> datas = getDataList(DataFactory.GOBLIN_STORE_KEY);
//        if(datas == null || datas.isEmpty()){
//            return false;
//        }
//        int bindPosition = 0;
//        int noBindPosition = 0;
//        for (GoblinStoreConfig data:datas){
//            if(data.storeType == SGCommonProto.E_STORE_TYPE.STORE_TYPE_GOBLIN_VALUE
//                    && data.show == 1){
//                bindPosition++;
//            }
//
//            if(data.storeType == SGCommonProto.E_STORE_TYPE.STORE_TYPE_GOBLIN_VALUE
//                    && data.show == 0){
//                noBindPosition++;
//            }
//        }
//        if(bindPosition < 3){
//            LogUtils.error("goblinStoteConfig storeType = 1 ,show = 1 ,times < 3 and times must >= 3");
//            return false;
//        }
//        if(noBindPosition < 5){
//            LogUtils.error("goblinStoreConfig storeType = 1 ,show = 1 ,times < 5 and tiems must >= 5");
//            return false;
//        }
//        return true;
//    }

    public List<PlayerLvConfig> getPlayerLvSectionList(int beforeLv,int currentLv){
        List<PlayerLvConfig> list =  getDataList(PLAYER_LV_KEY);
        List<PlayerLvConfig> lvReward = new CopyOnWriteArrayList<>();
        for(PlayerLvConfig playerLvConfig:list){
            if(playerLvConfig.id > beforeLv && playerLvConfig.id <= currentLv){
                lvReward.add(playerLvConfig);
            }
        }
        return lvReward;
    }

    /**
     *
     * @param lotteryConfig
     * @return
     */
    public boolean isMaxLevelLottery(LotteryConfig lotteryConfig)
    {
        List<LotteryConfig> list = getDataList(LOTTERY_KEY);
        int max = 0;
        for(LotteryConfig data : list)
        {
            if(data.type == lotteryConfig.type && data.level > max)
            {
                max = data.level;
            }
        }
        return lotteryConfig.level == max;
    }
    /**
     * 获取一级的奖池
     * @param type
     * @return
     */
    public LotteryConfig getInitLevelLottery(int type)
    {
        List<LotteryConfig> list = getDataList(LOTTERY_KEY);
        for(LotteryConfig data : list)
        {
            if(data.type == type && data.level == 1)
                return data;
        }
        return null;
    }

    /**
     * 获取下一级的奖池
     * @param type
     * @return
     */
    public LotteryConfig getNextLevelLottery(int type, int level)
    {
        List<LotteryConfig> list = getDataList(LOTTERY_KEY);
        for(LotteryConfig data : list)
        {
            if(data.type == type && data.level == level + 1)
                return data;
        }
        return null;
    }




    public LotteryConfig getLotteryConfig(int type,int level){
        List<LotteryConfig> list = getDataList(LOTTERY_KEY);
        for(LotteryConfig data : list)
        {
            if(data.type == type && data.level == level)
                return data;
        }
        return null;
    }

    public LotteryConfig getLotteryConfigByID(int id){
        List<LotteryConfig> list = getDataList(LOTTERY_KEY);
        for(LotteryConfig data : list)
        {
            if(data.id == id)
                return data;
        }
        return null;
    }


    private Map<String, String> wordMap = new ConcurrentHashMap<>();

    public void addWord(String key, String value)
    {
        wordMap.put(key, value);
    }

    public String getWord(String key, Object... params)
    {
        key = key.toLowerCase();
        String result = wordMap.get(key);
        if(result == null)
            return key;

        if(key.equals(WordFactory.ASSET_NOT_ENOUGH))
        {
            if(params.length > 0)
            {
                AssetConfig assetConfig = getGameObject(ASSET_KEY, Integer.parseInt(params[0].toString()));
                if(assetConfig != null)
                {
                    result = MessageFormat.format(result, assetConfig.name);
                }
            }
        }
        else if(key.equals(WordFactory.GOODS_NOT_ENOUGH))
        {
            if(params.length > 0)
            {
                PropConfig goods = getGameObject(PROP_KEY, Integer.parseInt(params[0].toString()));
                if(goods != null)
                {
                    result = MessageFormat.format(result, goods.name);
                }
            }
        }
        else if(key.equals(WordFactory.FUNCTION_NOT_OPEN))
        {
            if(params.length > 0)
            {
                FunctionConfig functionConfig = DataFactory.getInstance().getGameObject(DataFactory.FUNCTION_KEY, Integer.parseInt(params[0].toString()));
                if(functionConfig != null)
                {
                    result = MessageFormat.format(result, functionConfig.name);
                }
            }
        }
        else
        {
            if(params.length > 0)
            {
                result = MessageFormat.format(result, params);
            }
        }

        return result == null || result.length() == 0 ? key : result;
    }


    /**
     * 给卡初始化宿命列表
     */
    private void initCardFate()
    {
        List<CardConfig> cardConfigList = DataFactory.getInstance(LoadFactory.isTestLoad()).getDataList(DataFactory.CARD_KEY);
        for(CardConfig cardConfig : cardConfigList)
        {
            cardConfig.initFateList();
        }
    }

    public JSONArray getDetailDataToJson(int key)
    {
        List<GameObject> list = DataFactory.getInstance().getDataList(key);
        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = null;
        String value = null;
        for(GameObject gameObject : list)
        {
            jsonObject = new JSONObject();
            Field[] fields = gameObject.getClass().getFields();
            for(Field f : fields)
            {
                value = gameObject.getVariable(f.getName());
                if(StringUtils.isNullOrEmpty(value))
                    continue;

                jsonObject.put(f.getName(), value);
            }
            jsonArray.add(jsonObject);
        }
        return jsonArray;
    }

    public JSONArray getBaseDataToJson(int key)
    {
        List<GameObject> list = DataFactory.getInstance().getDataList(key);
        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = null;
        String value = null;
        for(GameObject gameObject : list)
        {
            jsonObject = new JSONObject();
            jsonObject.put("id", gameObject.id);
            jsonObject.put("name", gameObject.name);
            if(gameObject instanceof CityConfig)
                jsonObject.put("connCityIds", Arrays.toString(((CityConfig) gameObject).connCityIds));
            jsonArray.add(jsonObject);
        }
        return jsonArray;
    }





    public void checkConfig()
    {
        for(List<GameObject> list : dataList.values())
        {
            for(GameObject gameObject : list)
            {
                //注意注意，在所有Config类的check方法里面调用DataFactory.getInstance()方法必须传递LoadFactory.isTest(),必须写成DataFactory.getInstance(LoadFactory.isTest())
                if(!gameObject.check())
                {
                    addError(gameObject.getClass().getSimpleName(), "check", "error", gameObject.id);
                }
            }
        }

        ConfigFactory.check(this);

        for(E_StableDataType stableDataType : E_StableDataType.values())
        {
            if(getGameObject(DataFactory.STABLE_DATA_KEY, stableDataType.getCode()) == null)
            {
                LogUtils.error("E_StableDataType config is null -> " + stableDataType);
                addError(stableDataType.getClass().getSimpleName(), "check", "error", stableDataType.getCode());
            }
        }

        if(getMainCityByCamp(SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_BRIGHT_VALUE) == null)
        {
            LogUtils.error("CityConfig error -> no mainCity -> camp:" + SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_BRIGHT);
            addError(CityConfig.class.getSimpleName(), "check", "no mainCity", 0);
        }
        if(getMainCityByCamp(SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_BLOODY_VALUE) == null)
        {
            LogUtils.error("CityConfig error -> no mainCity -> camp:" + SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_BLOODY);
            addError(CityConfig.class.getSimpleName(), "check", "no mainCity", 0);
        }
        if(getMainCityByCamp(SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_DARK_VALUE) == null)
        {
            LogUtils.error("CityConfig error -> no mainCity -> camp:" + SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_DARK);
            addError(CityConfig.class.getSimpleName(), "check", "no mainCity", 0);
        }

        if (!checkStore()){
            addError(GoblinStoreConfig.class.getSimpleName(),"check"," group num error",0);
        }
    }

    /**
     * 验证商店表是否合理
     * @return
     */
    private boolean checkStore(){
        Map<Integer,CommonData> map = new HashMap<>();
        List<GoblinStoreConfig> configList = getDataList(DataFactory.GOBLIN_STORE_KEY);
        CommonData commonData;
        for (GoblinStoreConfig config:configList){
            if(config.storeType == SGCommonProto.E_STORE_TYPE.STORE_TYPE_EQUIP_VALUE || config.storeType == SGCommonProto.E_STORE_TYPE.STORE_TYPE_EXPLOIT_VALUE)
                continue;

            commonData = map.get(config.storeType);
            if (commonData == null){
                commonData = new CommonData();
                if (config.group == 0){
                    commonData.id += 1;
                }else if(config.group == 1){
                    commonData.value += 1;
                }
                map.put(config.storeType,commonData);
            }else{
                if (config.group == 0){
                    commonData.id += 1;
                }else if(config.group == 1){
                    commonData.value += 1;
                }
            }
        }

        for (Map.Entry<Integer,CommonData> entry : map.entrySet()){
            commonData = entry.getValue();
            if (commonData.id < 5){
                LogUtils.error("storeError type:" + entry.getKey() + " group:0 num < 5" + "  " + entry.getKey());
                return false;
            }

            if (commonData.value < 3){
                LogUtils.error("storeError type:" + entry.getKey() + " group:1 num < 3" + "  " + entry.getKey());
                return false;
            }
        }
        return true;
    }


    /************************************远征相关*****************************************/
    /**下标，总的权重**/
    private Map<Integer, Integer> expeditionWeightMap = new HashMap<>();

    private void initExpedition()
    {
        expeditionWeightMap.clear();

        List<ExpeditionConfig> configs = DataFactory.getInstance().getDataList(EXPEDITION_KEY);
        int size;
        for(ExpeditionConfig config : configs){
            size = config.weightList.size();
            for(int i = 0; i < size; i ++){
                Integer value = expeditionWeightMap.get(i + 1);
                value = value == null ? 0 : value.intValue();
                value += config.weightList.get(i);
                expeditionWeightMap.put(i + 1, value);
            }
        }
    }

    public int getNextExpeditionBossId(int nextLevel){
        List<ExpeditionConfig> configs = DataFactory.getInstance().getDataList(EXPEDITION_KEY);
        int maxTimesLength = configs.get(0).weightList.size();
        int index = Math.min(maxTimesLength - 1, nextLevel - 1);
        nextLevel = nextLevel > maxTimesLength ? maxTimesLength : nextLevel;
        int randomWeight = new Random().nextInt(expeditionWeightMap.get(nextLevel)) + 1;
        int sum = 0;
        for(ExpeditionConfig config : configs){
            sum += config.weightList.get(index);
            if(randomWeight <= sum){
                return config.id;
            }
        }
        return 0;
    }


    /*****初始化主将培养的总权重******/
    private int totalMasterTrainWeight = 0;
    private void initMasterTrain() {
        totalMasterTrainWeight = 0;
        List<MasterTrainConfig> configs = DataFactory.getInstance().getDataList(MASTER_TRAIN_KEY);
        for(MasterTrainConfig config : configs){
            totalMasterTrainWeight += config.weight;
        }

    }

    public void getMasterTrainChangeValue(int count, SGCommonProto.E_MASTER_TRAIN_TYPE type,  Map<Integer, Integer> lastChangeAttributes)
    {
        List<MasterTrainConfig> configs = DataFactory.getInstance().getDataList(MASTER_TRAIN_KEY);
        List<MasterTrainConfig> tempConfigs = new ArrayList<>(configs);
        int tempTotalMasterTrainWeight = totalMasterTrainWeight;
        List<MasterTrainConfig> attirbutes = new ArrayList<>();

        for(int i = 0; i < count;i++){
            MasterTrainConfig config = CoreUtils.getRandomObject(tempConfigs, tempTotalMasterTrainWeight, new ICalculateRandomField<MasterTrainConfig>() {
                @Override
                public int getFieldValue(MasterTrainConfig masterTrainConfig) {
                    return masterTrainConfig.weight;
                }
            });
            attirbutes.add(config);
            tempConfigs.remove(config);
            tempTotalMasterTrainWeight-=config.weight;
        }

        lastChangeAttributes.clear();
        for(MasterTrainConfig config : attirbutes){
            CommonData [] change = null;
            int totalChangeWeight = 0;
            if(type == SGCommonProto.E_MASTER_TRAIN_TYPE.MASTER_TRAIN_TYPE_SENIOR){
                change = config.seniorChange;
                totalChangeWeight = config.totalSeniorChangeWeight;
            }else {
                change = config.normalChange;
                totalChangeWeight = config.totalNormalChangeWeight;
            }

            CommonData data = CoreUtils.getRandomObject(change, totalChangeWeight, new ICalculateRandomField<CommonData>() {
                @Override
                public int getFieldValue(CommonData commonData) {
                    return commonData.value;
                }
            });
            lastChangeAttributes.put(config.id, data.id);
        }
    }
    /*************************阵营战相关************************************************************************************/
    private Map<Integer, List<CampRobotConfig>> campActivityRobotMap = new HashMap<>();
    public void initCampActivityRobot()
    {
        campActivityRobotMap.clear();

        List<CampRobotConfig> list = getDataList(CAMP_ROBOT_KEY);
        if(list == null || list.size() == 0)
        {
            addError("CampRobot", "check", "error", 0);
            LogUtils.error("CampRobot is null!");
            return;
        }
        List<CampRobotConfig> tempList = null;
        for(CampRobotConfig robot : list)
        {
            tempList = campActivityRobotMap.get(robot.type);
            if(tempList == null)
            {
                tempList = new ArrayList<>();
                campActivityRobotMap.put(robot.type, tempList);
            }

            tempList.add(robot);
        }
    }

    public List<CampRobotConfig> getCampRobotList(int type, int maxLv, int minLv)
    {
        List<CampRobotConfig> result = new CopyOnWriteArrayList<>();
        List<CampRobotConfig> list = campActivityRobotMap.get(type);
        if(list == null)
            return result;

        if(maxLv < minLv)
            return result;

        maxLv = maxLv < 1 ? 1 : maxLv;
        minLv = minLv < 0 ? 0 : minLv;

        LogUtils.info("max -> " + maxLv + " minLv -> " + minLv);

        for(CampRobotConfig campRobotConfig : list)
        {
            if(campRobotConfig.masterLv <= maxLv && campRobotConfig.masterLv >= minLv)
            {
                result.add(campRobotConfig);
            }
        }

        return result;
    }



    /**
     * 获取军团连锁
     * @param attrId
     * @return
     */
    public int getLegionChainValue(int attrId, int[] monsterLv)
    {
        int result = 0;

        int start = monsterLv.length > 8 ? 6 : 0;
        LegionChainConfig legionChain = DataFactory.getInstance().getGameObject(DataFactory.LEGION_CHAIN_KEY, E_LegionChinaType.EQUIP_INTENSIFY.getCode());
        result += legionChain.getAtt(attrId, monsterLv[start+0]-1);//配置文件配置的是从1开始的索引，为0表示没有，程序读取是从0开始的索引，所以要-1

        legionChain = DataFactory.getInstance().getGameObject(DataFactory.LEGION_CHAIN_KEY, E_LegionChinaType.EQUIP_MERGE.getCode());
        result += legionChain.getAtt(attrId, monsterLv[start+1]-1);

        legionChain = DataFactory.getInstance().getGameObject(DataFactory.LEGION_CHAIN_KEY, E_LegionChinaType.HERO_LEVEL.getCode());
        result += legionChain.getAtt(attrId, monsterLv[start+2]-1);

        legionChain = DataFactory.getInstance().getGameObject(DataFactory.LEGION_CHAIN_KEY, E_LegionChinaType.HERO_QUALITY.getCode());
        result += legionChain.getAtt(attrId, monsterLv[start+3]-1);

        legionChain = DataFactory.getInstance().getGameObject(DataFactory.LEGION_CHAIN_KEY, E_LegionChinaType.HERO_STAR.getCode());
        result += legionChain.getAtt(attrId, monsterLv[start+4]-1);

        legionChain = DataFactory.getInstance().getGameObject(DataFactory.LEGION_CHAIN_KEY, E_LegionChinaType.ACCESSORY_INTENSIFY.getCode());
        result += legionChain.getAtt(attrId, monsterLv[start+5]-1);

        legionChain = DataFactory.getInstance().getGameObject(DataFactory.LEGION_CHAIN_KEY, E_LegionChinaType.ACCESSORY_QUALITY.getCode());
        result += legionChain.getAtt(attrId, monsterLv[start+6]-1);

        legionChain = DataFactory.getInstance().getGameObject(DataFactory.LEGION_CHAIN_KEY, E_LegionChinaType.CARD_NUM.getCode());
        result += legionChain.getAtt(attrId, monsterLv[start+7]-1);

        return result;
    }


    /**
     * 获取阵营对应的主城
     * @param camp
     * @return
     */
    public CityConfig getMainCityByCamp(int camp)
    {
        List<CityConfig> cityConfigList = getDataList(CITY_KEY);
        if(cityConfigList == null)
            return null;

        for(CityConfig cityConfig : cityConfigList)
        {
            if(cityConfig.camp == camp && cityConfig.type == SGCommonProto.E_CITY_TYPE.CITY_TYPE_CAPITAL_VALUE)
            {
                return cityConfig;
            }
        }
        return null;
    }

    public int getMapIdByWorldMap(int camp)
    {
        StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.WORLD_MAP.getCode());
        if(stableDataConfig == null)
        {
            LogUtils.error("大地图配置错误");
            return 0;
        }
        for(GoodsData goodsData : stableDataConfig.goods)
        {
            if(goodsData.type == camp)
            {
                return goodsData.id;
            }
        }
        return 0;
    }


    public static List<WorldMapTaskBoxConfig> getBoxConfigListByGroup(int groupId)
    {
        List<WorldMapTaskBoxConfig> configList = new ArrayList<>();
        List<WorldMapTaskBoxConfig> allConfigList = DataFactory.getInstance().getDataList(DataFactory.WORLD_MAP_TASK_BOX);
        for (WorldMapTaskBoxConfig config: allConfigList){
            if(config.group == groupId){
                configList.add(config);
            }
        }
        return configList;
    }


    /****************************************天赋相关*********************************************/
    //天赋id： 天赋升级消耗及属性相关配置
    private Map<Integer, List<TalentUpConfig>> talentUpMap = new HashMap<>();
    //天赋id： 天赋精炼消耗及属性相关配置
    private Map<Integer, List<TalentRefineConfig>> talentRefineConfigMap = new HashMap<>();

    public void initTalent(){
        //天赋升级
        List<TalentUpConfig> list = getDataList(TALENT_UP);
        if(list == null || list.size() == 0)
        {
            addError("TalentUpConfig", "check", "error", 0);
            LogUtils.error("TalentUpConfig is null!");
            return;
        }
        List<TalentUpConfig> tempList = null;
        for(TalentUpConfig talent : list){
            if (talent.openRestrictions == 1) {
                if (talentUpMap.get(talent.talentId) == null) {
                    talentUpMap.put(talent.talentId, new ArrayList<>());
                    tempList = talentUpMap.get(talent.talentId);
                    if (tempList == null || tempList.size() == 0) {
                        tempList = new ArrayList<>();
                        tempList.add(talent);
                        talentUpMap.put(talent.talentId, tempList);
                        continue;
                    }
                }
                tempList = talentUpMap.get(talent.talentId);
                if (tempList == null || tempList.size() == 0) {
                    tempList = new ArrayList<>();
                    tempList.add(talent);
                    talentUpMap.put(talent.talentId, tempList);
                    continue;
                }
                tempList.add(talent);
            }
        }

        //天赋精炼
        List<TalentRefineConfig> refineConfigList = getDataList(TALENT_REFINE);
        if(refineConfigList == null || list.size() == 0)
        {
            addError("TalentRefineConfig", "check", "error", 0);
            LogUtils.error("TalentRefineConfig is null!");
            return;
        }
        List<TalentRefineConfig> refineList = null;

        for(TalentRefineConfig talent : refineConfigList){
            if (talent.openRestrictions == 1) {
                if (talentRefineConfigMap.get(talent.talentId) == null) {
                    talentRefineConfigMap.put(talent.talentId, new ArrayList<>());
                    refineList = talentRefineConfigMap.get(talent.talentId);
                    if (refineList == null || tempList.size() == 0) {
                        refineList = new ArrayList<>();
                        refineList.add(talent);
                        talentRefineConfigMap.put(talent.talentId, refineList);
                        continue;
                    }
                }
                refineList = talentRefineConfigMap.get(talent.talentId);
                if (refineList == null || tempList.size() == 0) {
                    refineList = new ArrayList<>();
                    refineList.add(talent);
                    talentRefineConfigMap.put(talent.talentId, refineList);
                    continue;
                }
                refineList.add(talent);
            }
        }
    }

    public Map<Integer, List<TalentRefineConfig>> getTalentRefineConfigMap() {
        return talentRefineConfigMap;
    }

    public Map<Integer, List<TalentUpConfig>> getTalentUpMap() {
        return talentUpMap;
    }



}
